package com.linjiahao.nettyBus.handler;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketFrameAggregator;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.stream.ChunkedWriteHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * @ClassName SocketChooseHandler
 * @Description: TODO
 * @Author linjiahao
 * @Date 2022/3/22
 **/
@Component
@Slf4j
@ChannelHandler.Sharable
public class SocketChooseHandler extends ChannelInboundHandlerAdapter {



    /**
     * WebSocket握手的协议前缀
     */
    private static final String WEBSOCKET_PREFIX = "GET /";

    private final static String match = "sec-websocket-protocol:([\\s\\S]*?)sec-websocket-version";



    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if(msg instanceof ByteBuf){
            ByteBuf byteBuf = Unpooled.wrappedBuffer((ByteBuf) msg);
            String protocol = getBufStart(byteBuf);
            if (protocol.startsWith(WEBSOCKET_PREFIX)) {
                //  websocket连接时，执行以下处理
                // HttpServerCodec：将请求和应答消息解码为HTTP消息
                ctx.pipeline().addLast("http-codec", new HttpServerCodec());
                // HttpObjectAggregator：将HTTP消息的多个部分合成一条完整的HTTP消息
                ctx.pipeline().addLast("aggregator", new HttpObjectAggregator(65535));
                // ChunkedWriteHandler：分块
                ctx.pipeline().addLast("http-chunked", new ChunkedWriteHandler());
                ctx.pipeline().addLast("WebSocketAggregator", new WebSocketFrameAggregator(65535));
                // 约定心跳，则主动断开channel释放资源
                ctx.pipeline().addLast(new NettyWebSocketAuthHandler());
            } else {
                ctx.pipeline().addLast(new StringDecoder());
                //后续改造自定义编解码
                ctx.pipeline().addLast(new StringEncoder());
                ctx.pipeline().addLast(new NettyServerHandler());
            }
            ctx.pipeline().remove(this.getClass());
        }else {
            log.info("无效连接");
        }
        super.channelRead(ctx,msg);
    }

    private String getBufStart(ByteBuf in) {
        int length = in.readableBytes();
        // 标记读位置
        in.markReaderIndex();
        byte[] content = new byte[length];
        in.readBytes(content);
        return new String(content);
    }




}
